home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok31.lha
/
Pute
/
Pute.imp
< prev
next >
Wrap
Text File
|
1993-08-15
|
4KB
|
181 lines
(*-------------------------------------------------------------------------
:Program. Pute
:Contents. Kleiner CLI-Taschenrechner
:Version. V1.0, Dezember 89, Fridtjof Siebert
:Author. Fridtjof Siebert
:Address. Nobileweg 67, D-7000 Suttgart 40
:CopyRight. PD
:Language. OBERON
:Compiler. AMOK OBORON Compiler, V0.2 beta
---------------------------------------------------------------------------*)
DEFINITION Pute; END Pute.
IMPLEMENTATION Pute;
(* $OvflChk- $RangeChk- $StackChk- $NilChk- $ReturnChk- $CaseChk- *)
IMPORT io, ol: OberonLib;
CONST
lparen = 0; rparen = 1; times = 2; plus = 3; minus = 4;
div = 5; mod = 6; number = 7; eof = -1;
TYPE
String = ARRAY 80 OF CHAR;
VAR
Sym: SHORTINT;
Number: LONGINT;
Char: CHAR;
buffer: POINTER TO String;
index: INTEGER;
Identifier: String;
result: LONGINT;
(*-------------------------------------------------------------------------*)
PROCEDURE ReadChar;
BEGIN
IF index=ol.dosCmdLen THEN
Char := 0X;
ELSE
Char := CAP(buffer^[index]); INC(index)
END;
END ReadChar;
(*-------------------------------------------------------------------------*)
PROCEDURE Error;
BEGIN
io.WriteString("Usage: PUTE <Expression>"); io.WriteLn; HALT(0)
END Error;
(*-------------------------------------------------------------------------*)
PROCEDURE GetSym();
VAR
digit: String; (* used to read constant numbers *)
cnt,i: INTEGER;
n: SHORTINT;
BEGIN
WHILE (Char<=" ") AND (Char>0X) DO ReadChar END;
CASE Char OF
"A".."Z":
cnt := 0;
WHILE (Char>="A") AND (Char<="Z") DO
Identifier[cnt] := Char;
ReadChar;
INC(cnt); IF cnt=80 THEN Error END;
END;
Identifier[cnt] := 0X;
IF Identifier="DIV" THEN Sym := div
ELSIF Identifier="MOD" THEN Sym := mod
ELSE Error END |
"0".."9":
cnt := -1;
WHILE ((Char>="0") AND (Char<="9")) OR ((Char>="A") AND (Char<="Z")) DO
INC(cnt);
IF cnt=80 THEN Error END;
digit[cnt] := Char;
ReadChar;
END;
Number := 0; i := 0;
IF digit[cnt]#"H" THEN
WHILE i<=cnt DO
n := SHORTINT(digit[i])-SHORTINT("0");
CASE n OF 0..9: Number := 10 * Number + n ELSE Error END;
INC(i);
END;
ELSE
WHILE i<cnt DO
n := SHORTINT(digit[i])-SHORTINT("0");
IF n>9 THEN DEC(n,7) END;
CASE n OF 0..15: Number := 16 * Number + n ELSE Error END;
INC(i);
END;
END;
Sym := number;
RETURN |
"(": Sym := lparen |
")": Sym := rparen |
"*": Sym := times |
"+": Sym := plus |
"-": Sym := minus |
"/": Sym := div |
0X : Sym := eof |
ELSE Error END;
ReadChar;
END GetSym;
(*-------------------------------------------------------------------------*)
PROCEDURE Expression(): LONGINT;
VAR
c: LONGINT;
addOperator: SHORTINT;
PROCEDURE Term(): LONGINT;
VAR
d,c: LONGINT;
s: SHORTINT;
PROCEDURE Factor(): LONGINT;
VAR c: LONGINT;
BEGIN
CASE Sym OF number: c := Number; GetSym |
lparen: GetSym; c:=Expression();
IF Sym#rparen THEN Error END;
GetSym |
ELSE Error END;
RETURN c
END Factor;
BEGIN
c := Factor();
LOOP
CASE Sym OF
times,div,mod:
s := Sym;
GetSym; d := Factor();
IF s=times THEN c := c * d;
ELSIF d=0 THEN HALT(0)
ELSIF s=div THEN c := c DIV d;
ELSE c := c MOD d END |
ELSE EXIT END;
END;
RETURN c;
END Term;
BEGIN
addOperator := Sym;
IF (addOperator=plus) OR (addOperator=minus) THEN GetSym END;
c := Term();
IF addOperator=minus THEN c := -c END;
LOOP
CASE Sym OF
plus : GetSym; INC(c,Term()) |
minus: GetSym; DEC(c,Term()) |
ELSE EXIT END;
END;
RETURN c;
END Expression;
BEGIN
IF ol.wbStarted THEN Error END;
buffer := ol.dosCmdBuf;
Char := " "; GetSym;
result := Expression(); IF Sym#eof THEN Error END;
io.WriteInt(result,11); io.WriteString(" = ");
io.WriteHex(result,8); io.Write("H"); io.WriteLn;
END Pute.